﻿using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using WeatheRx.Data;

namespace WeatheRx.Managers
{
    public interface IWorkOrderManager
    {
        WorkOrder Get(int workOrderId);

        void Store(WorkOrder workOrder);

        void StoreRange(List<WorkOrder> workOrders, bool deleteAllOthers = false);
    }

    public class WorkOrderManager : IWorkOrderManager
    {
        private readonly IWorkItemManager workItemManager;

        public WorkOrderManager(IWorkItemManager wm)
        {
            workItemManager = wm;
        }

        public WorkOrderManager()
        {
            workItemManager = new WorkItemManager();
        }

        public WorkOrder Get(int workOrderId)
        {
            WorkOrder result;
            using (var db = new HWAPEntities())
            {
                result = db.WorkOrders.FirstOrDefault(x => x.WorkOrderId == workOrderId);
                if (result == null) throw new ApplicationException("Work order was not found!");
            }
            return result;
        }

        public void Store(WorkOrder workOrder)
        {
            if (workOrder.WorkOrderId > 0)
                Update(workOrder);
            else
                Add(workOrder);
        }

        public void StoreRange(List<WorkOrder> workOrders, bool deleteAllOthers = false)
        {
            var addList = workOrders.Where(x => !(x.WorkOrderId > 0)).ToList();
            var updateList = workOrders.Where(x => x.WorkOrderId > 0).ToList();
            using (var db = new HWAPEntities())
            {
                updateList.ForEach(x =>
                {
                    var firstOrDefault = db.WorkOrders.FirstOrDefault(y => y.WorkOrderId == x.WorkOrderId);
                    if (firstOrDefault == null)
                    {
                        x.WorkOrderId = 0;
                        addList.Add(x);
                    }
                    else
                    {
                        Mapper.Map(x, firstOrDefault);
                    }
                });

                db.WorkOrders.AddRange(addList);
                if (deleteAllOthers)
                {
                    db.WorkOrders.Where(x => workOrders.All(y => !y.Equals(x)) && workOrders.Any(y => y.JobId == x.JobId)).ToList().ForEach(x => x.Deleted = true);
                }
                db.SaveChanges();
            }
        }

        private void Add(WorkOrder workOrder)
        {
            using (var db = new HWAPEntities())
            {
                db.WorkOrders.Add(workOrder);
                workOrder.WorkItems.ToList().ForEach(x => x.WorkOrderId = workOrder.WorkOrderId);
                db.SaveChanges();
            }
            workItemManager.StoreRange(workOrder.WorkItems.ToList(), false);
        }

        //Update Work order with work items
        private void Update(WorkOrder workOrder)
        {
            using (var db = new HWAPEntities())
            {
                var firstOrDefault = db.WorkOrders.FirstOrDefault(x => x.WorkOrderId == workOrder.WorkOrderId);
                if (firstOrDefault != null)
                {
                    Mapper.Map(workOrder, firstOrDefault);
                    db.SaveChanges();
                }
                else
                    Add(workOrder);
            }
            workItemManager.StoreRange(workOrder.WorkItems.ToList(), false);
        }
    }
}